package genedit.model;

import genedit.gui.GProjectTree;

import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.swing.SwingUtilities;
import javax.swing.tree.TreeNode;

/**
 * Klasa zadužena za organizaciju strukture projekta. Deca ovog čvora mogu biti
 * paketi ili dokumenti.
 * 
 * @author Nikola
 * @version 1.2 18/12/2013
 */
public class Package extends HierarchyElement {

	private static final long serialVersionUID = 1L;

	/**
	 * Brojač za generisanje podrazumevanog imena dece ovog čvora.
	 */
	private int elementCount = 0;

	/**
	 * Referenca na roditeljski čvor, drugi paket ili projekat.
	 */
	private HierarchyElement parent = null;

	/**
	 * Naziv paketa.
	 */
	private String name;

	// Neka stoji za sada
	private boolean isSaved;

	/**
	 * Lista čvorova koji su deca ovog elementa.
	 */
	private List<HierarchyElement> elements;

	public Package(HierarchyElement parent) {
		super();
		this.parent = parent;
	}

	public Package(HierarchyElement parent, String name) {
		super();
		this.parent = parent;
		this.name = name;
	}

	public HierarchyElement getParent() {
		return parent;
	}

	public String getName() {
		return name;
	}

	public void rename(String name) {
		this.name = name;
	}

	@Override
	public boolean isSaved() {
		return isSaved;
	}

	@Override
	public void setSaved(boolean saved) {
		this.isSaved = saved;
	}

	public List<HierarchyElement> getElements() {
		if (elements == null)
			elements = new java.util.ArrayList<HierarchyElement>();
		return elements;
	}

	public java.util.Iterator<HierarchyElement> getIteratorDocuments() {
		if (elements == null)
			elements = new java.util.ArrayList<HierarchyElement>();
		return elements.iterator();
	}

	public void setElements(java.util.Collection<HierarchyElement> newDocuments) {
		removeAllElements();
		for (java.util.Iterator<HierarchyElement> iter = newDocuments.iterator(); iter.hasNext();)
			addElements((HierarchyElement) iter.next());
	}

	public void addElements(HierarchyElement newElement) {
		if (newElement == null)
			return;
		if (this.elements == null)
			this.elements = new java.util.ArrayList<HierarchyElement>();
		if (!this.elements.contains(newElement))
			this.elements.add(newElement);
		sortElements();
		SwingUtilities.updateComponentTreeUI(GProjectTree.getInstance().getTree());
	}

	public void removeElements(HierarchyElement oldElement) {
		if (oldElement == null)
			return;
		if (this.elements != null)
			if (this.elements.contains(oldElement))
				this.elements.remove(oldElement);
		sortElements();
		SwingUtilities.updateComponentTreeUI(GProjectTree.getInstance().getTree());
	}

	public void sortElements() {
		for (int i = 0; i < elements.size() - 1; i++)
			for (int j = i; j < elements.size(); j++)
				if (elements.get(i) instanceof Document && elements.get(j) instanceof Package) {
					HierarchyElement temp = elements.get(i);
					elements.set(i, elements.get(j));
					elements.set(j, temp);
				}
	}

	public void removeAllElements() {
		if (elements != null)
			elements.clear();
		SwingUtilities.updateComponentTreeUI(GProjectTree.getInstance().getTree());
	}

	@Override
	public TreeNode getChildAt(int childIndex) {
		return getElements().get(childIndex);
	}

	@Override
	public int getChildCount() {
		return getElements().size();
	}

	@Override
	public int getIndex(TreeNode node) {
		return getElements().indexOf(node);
	}

	@Override
	public boolean getAllowsChildren() {
		return true;
	}

	@Override
	public boolean isLeaf() {
		return false;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Enumeration children() {
		return Collections.enumeration(getElements());
	}

	@Override
	public void removeChild(HierarchyElement he) {
		removeElements(he);
		super.removeChild(he);
	}

	public String toString() {
		return name;
	}

	public int getElementCount() {
		return ++elementCount;
	}

	public void setElementCount(int elementCount) {
		this.elementCount = elementCount;
	}
}